package com.zyy.study.jdk8NewFeatures;

import lombok.ToString;
import org.junit.Test;

import java.time.Instant;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * javq8新特性---Stream流
 */
public class StreamDemo {

    /**
     * 有一个字符串ID列表，现在需要将其转为User对象列表。可以使用map来实现：
     */
    @Test
    public void testMap() {
        List<String> ids = Arrays.asList("205", "105", "308", "469", "627", "193", "111");
        List<Data> dataList = ids.stream().map(id -> {
            Data data = new Data();
            data.setId(id);
            return data;
        }).collect(Collectors.toList());
        System.out.println(dataList);
    }

    /**
     * 现有一个句子列表，需要将句子中每个单词都提取出来得到一个所有单词列表
     */
    @Test
    public void testFlatMap() {
        List<String> sentences = Arrays.asList("hello world", "Jia Gou Wu Dao");
        List<String> collect = sentences.stream().flatMap(s -> {
            return Arrays.stream(s.split(" "));
        }).collect(Collectors.toList());
        System.out.println(collect);
    }

    @Test
    public void testParallelStream() {
        List<String> ids = Arrays.asList("205", "105", "308", "469", "627", "193", "111");
        List<String> stringList = ids.parallelStream().map(s -> {
            return "s" + s;
        }).collect(Collectors.toList());
        System.out.println(stringList);
    }

    /**
     * 串行执行任务
     * 串行任务执行时间：3203
     * [TransactionTask{transactionId=1}, TransactionTask{transactionId=2}, TransactionTask{transactionId=3}]
     */
    @Test
    public void testStreamForTransaction() {
        Instant start = Instant.now();
        List<String> list = Stream.of(
                new TransactionTask(1),
                new TransactionTask(2),
                new TransactionTask(3))
                .map(TransactionTask::doTransaction)
                .collect(Collectors.toList());
        Instant end = Instant.now();
        System.out.println("串行任务执行时间："+(end.toEpochMilli()-start.toEpochMilli()));
        System.out.println(list);
    }
    /**
     * 并行流执行任务
     * 并行任务执行时间：1125
     * [TransactionTask{transactionId=1}, TransactionTask{transactionId=2}, TransactionTask{transactionId=3}]
     */
    @Test
    public void testParallelStreamForTransaction(){
        Instant start = Instant.now();
        List<String> list = Stream.of(
                new TransactionTask(1),
                new TransactionTask(2),
                new TransactionTask(3))
                .parallel()
                .map(TransactionTask::doTransaction)
                .collect(Collectors.toList());
        Instant end = Instant.now();
        System.out.println("并行任务执行时间："+(end.toEpochMilli()-start.toEpochMilli()));
        System.out.println(list);
    }

    /**
     * 串行创建异步任务
     * completableFuture任务执行时间：1125
     * [TransactionTask{transactionId=1}, TransactionTask{transactionId=2}, TransactionTask{transactionId=3}]
     */
    @Test
    public void testCompletableForTransaction(){
        Instant start = Instant.now();
        List<CompletableFuture<String>> completableFutureList = Stream.of(
                new TransactionTask(1),
                new TransactionTask(2),
                new TransactionTask(3))
                .map(transactionTask -> {
                    return CompletableFuture.supplyAsync(() -> {
                        return transactionTask.doTransaction();
                    });
                })
                .collect(Collectors.toList());
        List<String> list = completableFutureList.stream()
                .map(completableFuture -> {
                    return completableFuture.join();
                }).collect(Collectors.toList());
        Instant end = Instant.now();
        System.out.println("completableFuture任务执行时间："+(end.toEpochMilli()-start.toEpochMilli()));
        System.out.println(list);
    }


}

@ToString
class Data {
    private String id;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }
}
